module z80_sram_ctrl #(
    parameter ADDR = 24'h000000,
    parameter MREQ_CYCLES   = 5,   // 50 ns
    parameter WR_ACTIVE_CYC = 10,  // 100 ns
    parameter WR_HOLD_CYC   = 5    // 50 ns
)(
    input  wire        clk,
    input  wire        rst_n,
    input  wire        apb_psel_in,
    input  wire        apb_penable_in,
    input  wire        apb_pwrite_in,
    input  wire [31:0] apb_paddr_in,
    input  wire [31:0] apb_pwdata_in,
    output reg         apb_pready_out,
    output reg [31:0]  sram_ad_out,
    output reg         sram_cs_out,
    output reg         sram_we_out,
    output reg         sram_oe_out
);

localparam IDLE      = 3'd0;
localparam MREQ_WAIT = 3'd1;
localparam WR_ASSERT = 3'd2;
localparam WR_HOLD   = 3'd3;
localparam DONE      = 3'd4;

reg [2:0]  state;
reg [15:0] cnt;

// *** IMPORTANT FIX: sample start in APB data phase (psel=1 && penable=1)
wire start_write = apb_psel_in && apb_penable_in && apb_pwrite_in && apb_pready_out;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        state <= IDLE;
        cnt   <= 0;
        sram_cs_out <= 1'b0; // inactive (high-active device => 0 means de-assert)
        sram_we_out <= 1'b0;
        sram_oe_out <= 1'b0;
        apb_pready_out <= 1'b1; // ready by default
        sram_ad_out <= 32'd0;
    end else begin
        case(state)
        IDLE: begin
            apb_pready_out <= 1'b1;
            sram_cs_out    <= 1'b0;
            sram_we_out    <= 1'b0;
            sram_oe_out    <= 1'b0;
            cnt <= 0;
            if(start_write) begin
                sram_ad_out[7:0]    <= apb_pwdata_in[7:0];     // data or A7-A0
                sram_ad_out[31:16]  <= apb_pwdata_in[31:16];    // A15-A8 (note: kept your mapping)
                apb_pready_out <= 1'b0; // extend APB transfer until we finish
                cnt <= 0;
                state <= MREQ_WAIT;
            end
        end

        MREQ_WAIT: begin
            // wait MREQ_CYCLES (e.g. address setup time)
            if(cnt < MREQ_CYCLES) begin
                cnt <= cnt + 1;
            end else begin
                // assert chip select (HIGH active)
                sram_cs_out <= 1'b1;
                cnt <= 0;
                state <= WR_ASSERT;
            end
        end

        WR_ASSERT: begin
            // assert WE (HIGH active) to start write
            // keep WE asserted for WR_ACTIVE_CYC cycles
            if(cnt == 0) begin
                sram_we_out <= 1'b1;
            end
            if(cnt < WR_ACTIVE_CYC) begin
                cnt <= cnt + 1;
            end else begin
                // de-assert WE (write finished)
                sram_we_out <= 1'b0;
                cnt <= 0;
                state <= WR_HOLD;
            end
        end

        WR_HOLD: begin
            // hold chip select or address stable for WR_HOLD_CYC cycles
            if(cnt < WR_HOLD_CYC) begin
                cnt <= cnt + 1;
            end else begin
                // de-assert CS (HIGH-active device -> set 0)
                sram_cs_out <= 1'b0;
                cnt <= 0;
                state <= DONE;
            end
        end

        DONE: begin
            // finish APB transfer
            apb_pready_out <= 1'b1;
            // clear control outputs to safe defaults (already done in next IDLE)
            state <= IDLE;
        end

        default: begin
            state <= IDLE;
        end

        endcase
    end
end
endmodule
